package org.firefly.tool.file;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bson.Document;

import com.mongodb.client.MongoCollection;

public class BigFileReader {
	public static void main(String[] args) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");

		File file = new File("/data/nginx_logs/docker- api_access.log20200420");
		BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
		BufferedReader reader = new BufferedReader(new InputStreamReader(fis, "utf-8"), 200 * 1024 * 1024);// 用5M的缓冲读取文本文件
		String dbName = "nginx_log";
		String collName = "c_20";
		MongoCollection<Document> coll = MongoUtil.instance.getCollection(dbName, collName);
		String line = "";
		int y = 1;
		List<Document> list = new ArrayList<>();
		while ((line = reader.readLine()) != null) {
			y++;
			Document d = new Document();
			String ip = line.substring(0, line.indexOf(" - - "));
			d.put("ip", ip);
			String date = line.substring(line.indexOf("[") + 1, line.indexOf("]"));

			Date newStr = sdf.parse(date);
			SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			d.put("date", s.format(newStr));
			int i = 1;
			line = line.replaceAll("\"", "*");

			int size = line.indexOf("*");
			while (size > 0) {
				i++;
				int sourceSize = size;
				size = line.indexOf("*", size + 1);
				switch (i) {
				case 2:
					String request = (line.substring(sourceSize + 1, size));

					if (null != request) {
						if (request.contains("/") && request.contains("?")) {
							String url = request.substring(request.indexOf("/"), request.indexOf("?"));
							d.put("url", url);
							Map<String, String> m = BigFileReader.params(BigFileReader.TruncateUrlPage(request));
							d.putAll(m);
						} else {
							d.put("url", request);
						}
					}

					break;
				case 4:
					String status = (line.substring(sourceSize + 1, size));
					d.put("status", status);
					break;
				case 6:
					String http_range = (line.substring(sourceSize + 1, size));
					break;
				case 8:
					String http_referer = (line.substring(sourceSize + 1, size));
					break;
				case 10:
					String http_user_agent = (line.substring(sourceSize + 1, size));
					break;
				case 12:
					String request_time = (line.substring(sourceSize + 1, size));
					d.put("request_time", request_time);
					break;
				case 14:
					String host = (line.substring(sourceSize + 1, size));
					break;
				case 16:
					String server_port = (line.substring(sourceSize + 1, size));
					break;
				case 18:
					String sent_http_location = (line.substring(sourceSize + 1, size));
					break;
				case 20:
					String upstream_cache_status = (line.substring(sourceSize + 1, size));
					d.put("upstream_cache_status", upstream_cache_status);
					break;
				case 22:
					String upstream_addr = (line.substring(sourceSize + 1, size));
					break;
				case 24:
					String upstream_status = (line.substring(sourceSize + 1, size));
					d.put("upstream_status", upstream_status);
					break;
				case 26:
					String upstream_response_time = (line.substring(sourceSize + 1, size));
					d.put("upstream_response_time", upstream_response_time);
					break;
				default:
					break;
				}

			}
			list.add(d);
			// 保存到mongo
			if (y == 1000) {
				coll.insertMany(list);
				list = new ArrayList<Document>();
				y = 1;
			}
		}

	}

	public static String TruncateUrlPage(String strURL) {
		String strAllParam = null;
		String[] arrSplit = null;

		strURL = strURL.trim();

		arrSplit = strURL.split("[?]");
		if (strURL.length() > 1) {
			if (arrSplit.length > 1) {
				if (arrSplit[1] != null) {
					strAllParam = arrSplit[1];
				}
			}
		}
		return strAllParam;
	}

	public static Map<String, String> params(String u) {
		Map<String, String> mapRequest = new HashMap<String, String>();
		String strUrlParam = u;
		if (strUrlParam == null) {
			return mapRequest;
		}
		 
		String[] arrSplit = strUrlParam.split("&");
		for (String strSplit : arrSplit) {
			String[] arrSplitEqual = null;
			arrSplitEqual = strSplit.split("=");

			// 解析出键值
			if (arrSplitEqual.length > 1) {
				String key = arrSplitEqual[0];
				if (key.equalsIgnoreCase("custId") || key.equalsIgnoreCase("uid") || key.equalsIgnoreCase("desktopId"))
					// 正确解析
					mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);

			} else {
				if (arrSplitEqual[0] != "") {
					// 只有参数没有值，不加入
					// mapRequest.put(arrSplitEqual[0], "");
				}
			}
		}
		return mapRequest;

	}
}
